/*
 * File    : Peer.java
 * Created : 01-Dec-2003
 * By      : parg
 * 
 * Azureus - a Java Bittorrent client
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details ( see the LICENSE file ).
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.gudy.azureus2.plugins.peers;

/**
 * @author parg
 *
 */

import java.util.List;

import org.gudy.azureus2.core3.peer.PEPeer;
import org.gudy.azureus2.plugins.messaging.Message;
import org.gudy.azureus2.plugins.network.Connection;
import org.gudy.azureus2.plugins.network.ConnectionStub;
import org.gudy.azureus2.plugins.network.RateLimiter;

public interface Peer {
    public final static int CONNECTING = PEPeer.CONNECTING;
    public final static int HANDSHAKING = PEPeer.HANDSHAKING;
    public final static int TRANSFERING = PEPeer.TRANSFERING;
    public final static int CLOSING = PEPeer.CLOSING;
    public final static int DISCONNECTED = PEPeer.DISCONNECTED;

    public final static Object PR_PRIORITY_CONNECTION = new Object();
    public final static Object PR_PROTOCOL = new Object();

    public void bindConnection(ConnectionStub stub);

    public PeerManager getManager();

    public int getState(); // from above set

    public byte[] getId();

    /**
     * Get the peer's local TCP connection port.
     * 
     * @return local port
     */

    public String getIp();

    /**
     * Get the TCP port this peer is listening for incoming connections on.
     * 
     * @return TCP port, or 0 if port is unknown
     */
    public int getTCPListenPort();

    /**
     * Get the UDP port this peer is listening for incoming connections on.
     * 
     * @return UDP port, or 0 if port is unknown
     */
    public int getUDPListenPort();

    /**
     * Get the UDP port this peer is listening on for non-data connections
     * 
     * @return
     */

    public int getUDPNonDataListenPort();

    public int getPort();

    public boolean[] getAvailable();

    /**
     * @param pieceNumber
     *            int
     * @return true if this peers makes this piece available
     */
    public boolean isPieceAvailable(int pieceNumber);

    public boolean isTransferAvailable();

    /**
     * Rate control - gives the maximum number of bytes that can be read from this connection at this time and returns the actual number read
     * 
     * @param max
     * @return
     */

    public int readBytes(int max);

    public int writeBytes(int max);

    /**
     * This is much list isTransferAvailable(), except is more comprehensive. That is; it checks a few more factors, within the object for speed, so
     * that a more timely status is considered and the caller doesn't need to try to check each thing on it's own.
     * 
     * @return true if several factors say downloading can be tried.
     */
    public boolean isDownloadPossible();

    public boolean isChoked();

    public boolean isChoking();

    public boolean isInterested();

    public boolean isInteresting();

    public boolean isSeed();

    public boolean isSnubbed();

    public long getSnubbedTime();

    public void setSnubbed(boolean b);

    public PeerStats getStats();

    public boolean isIncoming();

    /**
     * @deprecated This erroneously returns percent in 1000 (i.e. 100% = 1000 :) Therefore replaces with something more accurately named!
     * @return
     */

    public int getPercentDone();

    public int getPercentDoneInThousandNotation();

    public String getClient();

    public boolean isOptimisticUnchoke();

    public void setOptimisticUnchoke(boolean is_optimistic);

    public List getExpiredRequests();

    public List getRequests();

    public int getMaximumNumberOfRequests();

    public int getNumberOfRequests();

    public void cancelRequest(PeerReadRequest request);

    public boolean requestAllocationStarts(int[] base_priorities);

    public int[] getPriorityOffsets();

    public void requestAllocationComplete();

    public boolean addRequest(PeerReadRequest request);

    public void close(String reason, boolean closedOnError, boolean attemptReconnect);

    public int getPercentDoneOfCurrentIncomingRequest();

    public int[] getOutgoingRequestedPieceNumbers();

    public int getOutgoingRequestCount();

    public int getPercentDoneOfCurrentOutgoingRequest();

    /**
     * Add peer listener.
     * 
     * @param listener
     * @deprecated use addListener( PeerListener2 )
     */
    public void addListener(PeerListener listener);

    /**
     * Remove peer listener.
     * 
     * @param listener
     * @deprecated use removeListener( PeerListener2 )
     */
    public void removeListener(PeerListener listener);

    /**
     * Add peer listener.
     * 
     * @param listener
     */
    public void addListener(PeerListener2 listener);

    /**
     * Remove peer listener.
     * 
     * @param listener
     */
    public void removeListener(PeerListener2 listener);

    /**
     * Get the network connection that backs this peer.
     * 
     * @return connection
     */
    public Connection getConnection();

    /**
     * Whether or not this peer supports the advanced messaging API.
     * 
     * @return true if extended messaging is supported, false if not
     */
    public boolean supportsMessaging();

    /**
     * Get the list of messages that this peer and us mutually understand.
     * 
     * @return messages available for use, or null of supported is yet unknown
     */
    public Message[] getSupportedMessages();

    public void setUserData(Object key, Object value);

    public Object getUserData(Object key);

    public byte[] getHandshakeReservedBytes();

    public boolean isPriorityConnection();

    public void setPriorityConnection(boolean is_priority);

    /**
     * @since 4.7.0.3
     * @param limiter
     *            create via ConnectionManager
     * @param is_upload
     *            false -> download limit
     */

    public void addRateLimiter(RateLimiter limiter, boolean is_upload);

    public void removeRateLimiter(RateLimiter limiter, boolean is_upload);

    public RateLimiter[] getRateLimiters(boolean is_upload);
}
